const Koa = require('koa');
const Router = require('koa-router');
const multer = require('@koa/multer');
const path = require('path');
const fs = require('fs');
// 使用内置轻量数据库：sqlite3
let sqlite3;
try {
    sqlite3 = require('sqlite3').verbose();
} catch (e) {
    console.warn('未找到 sqlite3 依赖，若报错请先安装: npm i sqlite3');
}
const app = new Koa();
const router = new Router();

/** 保留文件系统目录，仅用于兼容已有上传，不再作为播放源 */
const uploadsDir = path.join(__dirname, 'uploads');
if (!fs.existsSync(uploadsDir)) {
    fs.mkdirSync(uploadsDir, { recursive: true });
    console.log('✓ uploads 目录已创建');
}

/** 初始化数据库 */
let db;
if (sqlite3) {
    const dbPath = path.join(__dirname, 'music.db');
    db = new sqlite3.Database(dbPath);
    db.serialize(() => {
        db.run(`CREATE TABLE IF NOT EXISTS audio_files (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            filename TEXT,
            mime TEXT,
            size INTEGER,
            data BLOB,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        )`);
    });
    console.log('✓ 数据库初始化完成:', path.join(__dirname, 'music.db'));
}

// CORS 中间件
app.use(async (ctx, next) => {
    ctx.set('Access-Control-Allow-Origin', '*');
    ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    ctx.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    
    if (ctx.method === 'OPTIONS') {
        ctx.status = 200;
        return;
    }
    
    await next();
});

// 静态文件服务 - 支持音频文件播放
app.use(async (ctx, next) => {
    if (ctx.path.startsWith('/uploads/')) {
        const filePath = path.join(__dirname, ctx.path);
        
        // 检查是否为目录
        if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
            ctx.status = 403;
            ctx.body = { error: 'Directory access not allowed' };
            return;
        }
        
        if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
            const ext = path.extname(filePath).toLowerCase();
            
            // 设置正确的 MIME 类型
            switch (ext) {
                case '.mp3':
                    ctx.type = 'audio/mpeg';
                    break;
                case '.wav':
                    ctx.type = 'audio/wav';
                    break;
                case '.m4a':
                    ctx.type = 'audio/mp4';
                    break;
                case '.aac':
                    ctx.type = 'audio/aac';
                    break;
                case '.flac':
                    ctx.type = 'audio/flac';
                    break;
                default:
                    ctx.type = 'audio/mpeg';
            }
            
            // 支持范围请求（重要：用于音频流播放）
            const stat = fs.statSync(filePath);
            const range = ctx.headers.range;
            
            if (range) {
                const parts = range.replace(/bytes=/, "").split("-");
                const start = parseInt(parts[0], 10);
                const end = parts[1] ? parseInt(parts[1], 10) : stat.size - 1;
                const chunksize = (end - start) + 1;
                
                ctx.status = 206;
                ctx.set({
                    'Content-Range': `bytes ${start}-${end}/${stat.size}`,
                    'Accept-Ranges': 'bytes',
                    'Content-Length': chunksize,
                    'Cache-Control': 'no-cache'
                });
                
                ctx.body = fs.createReadStream(filePath, { start, end });
            } else {
                ctx.set({
                    'Content-Length': stat.size,
                    'Accept-Ranges': 'bytes',
                    'Cache-Control': 'no-cache'
                });
                ctx.body = fs.createReadStream(filePath);
            }
            return;
        }
    }
    await next();
});

// 文件上传配置
const upload = multer({
    dest: uploadsDir,
    limits: { 
        fileSize: 50 * 1024 * 1024 // 50MB
    }
});

/** 旧路由保留（写入文件系统），但播放将改走数据库接口 */
router.post('/api/upload/audio', upload.single('audio'), async (ctx) => {
    try {
        if (!ctx.file) {
            ctx.status = 400;
            ctx.body = { code: -1, message: '没有收到文件' };
            return;
        }
        const file = ctx.file;
        const ext = path.extname(file.originalname);
        const newFilename = file.filename + ext;
        fs.renameSync(file.path, path.join(uploadsDir, newFilename));
        ctx.body = {
            code: 0,
            message: '上传成功(文件系统)',
            data: {
                filename: newFilename,
                originalname: file.originalname,
                size: file.size,
                url: `http://172.29.99.148:3000/uploads/${newFilename}`
            }
        };
    } catch (error) {
        ctx.status = 500;
        ctx.body = { code: -1, message: '上传失败: ' + error.message };
    }
});

/** 新路由：上传到数据库 (BLOB) */
router.post('/api/upload/audio-db', upload.single('audio'), async (ctx) => {
    try {
        if (!ctx.file) {
            ctx.status = 400;
            ctx.body = { code: -1, message: '没有收到文件' };
            return;
        }
        if (!db) {
            ctx.status = 500;
            ctx.body = { code: -1, message: '数据库未初始化，请安装 sqlite3 并重启服务器' };
            return;
        }
        const file = ctx.file;
        const mime = file.mimetype || 'audio/mpeg';
        const size = file.size || 0;
        const buffer = fs.readFileSync(file.path); // 读取临时文件数据
        // 插入数据库
        await new Promise((resolve, reject) => {
            db.run(
                `INSERT INTO audio_files (filename, mime, size, data) VALUES (?, ?, ?, ?)`,
                [file.originalname, mime, size, buffer],
                function (err) {
                    if (err) return reject(err);
                    resolve(this.lastID);
                }
            );
        }).then((lastID) => {
            // 清理临时文件
            try { fs.unlinkSync(file.path); } catch (_) {}
            ctx.body = {
                code: 0,
                message: '上传成功(数据库)',
                data: {
                    id: lastID,
                    filename: file.originalname,
                    mime,
                    size,
                    url: `http://172.29.99.148:3000/api/audio/${lastID}`
                }
            };
        }).catch((e) => {
            throw e;
        });
    } catch (error) {
        console.error('上传失败:', error);
        ctx.status = 500;
        ctx.body = { code: -1, message: '上传失败: ' + error.message };
    }
});

/** 数据库播放接口：支持 HEAD 与 Range */
router.head('/api/audio/:id', async (ctx) => {
    if (!db) { ctx.status = 500; return; }
    const id = parseInt(ctx.params.id, 10);
    await new Promise((resolve) => {
        db.get(`SELECT mime, size FROM audio_files WHERE id = ?`, [id], (err, row) => {
            if (err || !row) {
                ctx.status = 404; return resolve();
            }
            ctx.set('Content-Type', row.mime || 'audio/mpeg');
            ctx.set('Content-Length', row.size || 0);
            ctx.set('Accept-Ranges', 'bytes');
            ctx.set('Cache-Control', 'no-cache');
            ctx.status = 200;
            resolve();
        });
    });
});

router.get('/api/audio/:id', async (ctx) => {
    if (!db) { ctx.status = 500; ctx.body = 'DB not initialized'; return; }
    const id = parseInt(ctx.params.id, 10);
    await new Promise((resolve) => {
        db.get(`SELECT mime, size, data FROM audio_files WHERE id = ?`, [id], (err, row) => {
            if (err || !row) {
                ctx.status = 404; ctx.body = 'Not found'; return resolve();
            }
            const mime = row.mime || 'audio/mpeg';
            const size = row.size || (row.data ? row.data.length : 0);
            const buffer = row.data ? Buffer.from(row.data) : Buffer.alloc(0);
            ctx.set('Content-Type', mime);
            ctx.set('Accept-Ranges', 'bytes');
            ctx.set('Cache-Control', 'no-cache');

            const range = ctx.headers.range;
            if (range && size > 0) {
                const parts = range.replace(/bytes=/, "").split("-");
                const start = parseInt(parts[0], 10);
                const end = parts[1] ? parseInt(parts[1], 10) : size - 1;
                const chunksize = (end - start) + 1;
                ctx.status = 206;
                ctx.set('Content-Range', `bytes ${start}-${end}/${size}`);
                ctx.set('Content-Length', chunksize);
                ctx.body = buffer.subarray(start, end + 1);
            } else {
                ctx.status = 200;
                ctx.set('Content-Length', size);
                ctx.body = buffer;
            }
            resolve();
        });
    });
});

// 健康检查
router.get('/health', async (ctx) => {
    ctx.body = { status: 'ok', message: '服务器运行正常' };
});

// 根路由
router.get('/', async (ctx) => {
    ctx.body = { message: '音乐上传服务器运行中', version: '1.0.0' };
});

// 使用路由
app.use(router.routes());
app.use(router.allowedMethods());

// 启动服务器
const PORT = 3000;
const HOST = '0.0.0.0';

app.listen(PORT, HOST, () => {
    console.log(`🎵 音乐上传服务器已启动`);
    console.log(`📡 服务器地址: http://localhost:${PORT}`);
    console.log(`📡 外网地址: http://172.29.99.148:${PORT}`);
    console.log(`📁 上传目录: ${uploadsDir}`);
    console.log(`🚀 上传接口: http://172.29.99.148:${PORT}/api/upload/audio`);
    console.log(`✅ 服务器已准备就绪，可以开始上传音频文件！`);
});